package org.marketlive.biz.account;

import org.marketlive.entity.account.IAccountSet;
import org.marketlive.entity.account.ICustomer;
import org.marketlive.entity.account.IContact;

/*
(C) Copyright MarketLive. 2006. All rights reserved.
MarketLive is a trademark of MarketLive, Inc.
Warning: This computer program is protected by copyright law and international treaties.
Unauthorized reproduction or distribution of this program, or any portion of it, may result
in severe civil and criminal penalties, and will be prosecuted to the maximum extent
possible under the law.
*/

import org.marketlive.entity.account.IHint;

import java.util.Set;
import java.util.List;


/**
 * Main business logic interface for performing all necessary account
 * operations.
 *
 */
public interface IAccountManager {

  /**
   * Creates a customer with minimum info required and sets the guest property in the customer entity.
   *
   * @param accountSet the AccountSet which the new customer will be assoctiated to
   * @param email the user's email address
   * @param userName the user's name (currently, the email address is used for the user name)
   * @param password the user password
   * @param isGuest flag to set guest property of customer
   * @return a newly created customer; null if the operation failed or the userName is taken
   */
  ICustomer createCustomer(IAccountSet accountSet, final String email, final String userName, 
                            final String password, final boolean isGuest);
  
  /**
   * Finds the registered customer with the given user name.
   *
   * @param userName user name of the customer to find
   * @return the {@link ICustomer}, or null if no ICustomer exists with that userName
   */
  ICustomer findCustomer(IAccountSet accontSet, final String userName);

  /**
   * Finds the registered {@link ICustomer} with the given email address.
   *
   * @param email email address of the ICustomer to be found
   * @return the ICustomer or null if no ICustomer exists with that email
   */
  ICustomer findCustomerByEmail(IAccountSet accountSet, final String email);

  /**
   * Finds the registered {@link ICustomer} with the given customerPK value.
   *
   * @param pk pk of the ICustomer to be found
   * @return the ICustomer or null if no ICustomer exists with that pk
   */
  ICustomer findCustomerByPk(final String pk);

  /**
   * Checks whether there is already such a customer before trying to create one.
   *
   * @param email the email address to find
   * @return true if a customer with the given email address is found
   * @deprecated as of MarketLive 5.4,
   *               replaced by {@link #isCustomerTaken(IAccountSet accountSet, final String email)}
   */
  boolean isCustomerTaken(final String email);
  
  /**
   * Checks whether there is already such a customer in the input <code>IAccountSet</code> 
   * before trying to create one.
   *
   * @param accountSet the AccountSet by which to search for the customer from
   * @param email the email address to find
   * @return true if a customer with the given email address is found
   */
  boolean isCustomerTaken(IAccountSet accountSet, final String email);
  
  /**
   *  Updates password recovery information for a given {@link ICustomer}.
   *
   * @param customer current ICustomer, in most cases the newly created ICustomer
   * @param hint reference to the {@link IHint} with the question chosen by the shopper for password recovery
   * @param hintAnswer the answer the shopper provided for password recovery
   * @return true if the password recovery was successfully persisted
   */
  boolean updatePasswordRecoveryInfo(ICustomer customer, IHint hint, String hintAnswer);

  /**
   *  Updates {@link ICustomer} email and username only.
   *
   * @param customer the ICustomer object to update
   * @param email   the new email
   * @param userName the new user name
   * @return true on success
   */
  boolean updateCustomer(ICustomer customer, String email, String userName);

  /**
   *  Updates minimum info about the {@link ICustomer}.
   *
   * @param customer the ICustomer object to update
   * @param email   the new email address
   * @param userName the new user name
   * @param password  the new password
   * @return true on success
   */
  boolean updateCustomer(ICustomer customer, String email, String userName, String password);

  /**
   *  Updates minimum info about the {@link ICustomer}.
   *
   * @param customer the ICustomer object to update
   * @param email   the new email address
   * @param userName the new user name
   * @param password  the new password
   * @param isGuest flag to set guest property of ICustomer
   * @return true on success
   */
  boolean updateCustomer(ICustomer customer, String email, String userName, String password, final boolean isGuest);

  /**
   *  Updates info about the {@link ICustomer}.
   *
   * @param customer the ICustomer object to update
   * @param email   the new email address
   * @param userName the new user name
   * @param password  the new password
   * @param hint reference to the {@link IHint} with the new question
   * @param hintAnswer the new hint answer
   * @return true on success
   */
  boolean updateCustomer(ICustomer customer, String email, String userName, String password, IHint hint,
                         String hintAnswer);

  /**
   * Removes an {@link ICustomer} record.
   *
   * @param customer the ICustomer to remove
   */
  void removeCustomer(ICustomer customer);

  /**
   * Returns a {@link List} of {@link IOrder}s with history info.
   *
   * @param orders the {@link Set} of IOrders for which history info is retrieved
   * @return a List of IOrders with history info
   */
  List getOrderHistoryForCustomer(Set orders);

  /**
   * Updates a customer record.
   *
   * @param customer the {@link ICustomer} to update
   */
  void updateCustomer(ICustomer customer);

  /**
   * Checks if encrypted password matches password from database.
   *
   * @param customer the {@link ICustomer} to check the password on
   * @param password the password to verify
   * @return true if password matches the one in the database
   */
  boolean confirmCustomerPassword(ICustomer customer, String password);

  /**
   * Compares two encrypted passwords and returns true if they are equal.
   *
   * @param encryptedPassword1 the first encrypted password
   * @param encryptedPassword2 the second encrypted password
   * @return true if passwords match
   */
  boolean comparePasswords(String encryptedPassword1, String encryptedPassword2);

  /**
   * Encrypts a customer password.
   *
   * @param password the password to encrypt
   * @return encrypted password
   */
  String encryptCustomerPassword(String password);  
}
